#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QSerialPort>
#include <QSerialPortInfo>

//圆圈内  半圈线的数量
int LINECOUNT=6;
//圆圈的  数量
int CIRCLECOUNT=6;
//显示界面的距离
int SHOWDISTANCE=100;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
//    this->showMaximized();
    //ui界面刷新定时器
    p_timer = new QTimer();
    connect(p_timer,SIGNAL(timeout()),this,SLOT(timerTimeOut()));
    p_timer->start(10);     //开启定时器，10ms溢出一次

    //定时器关联更新串口号槽函数
    timer = new QTimer;
    connect(timer,&QTimer::timeout,this,&MainWindow::UpdatePort);//更新串口号
    timer->start(100);

    //查找可用的串口
    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            //将串口号添加到 PortBox
            ui->PortBox->addItem(serial.portName());
            //关闭串口，等待人为打开
            serial.close();
        }
    }
    //设置波特率下拉菜单默认显示第0项
    ui->BaudBox->setCurrentIndex(4);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//打开串口按钮 点击事件
void MainWindow::on_OpenSerialButton_clicked()
{
    if(ui->OpenSerialButton->text() == "打开串口")
    {
        if(ui->PortBox->currentIndex() == -1)
        {
            QMessageBox::warning(this , "error!" , "No Port!", 0, 0, QMessageBox::Ok | QMessageBox::Default);
            return;
        }

        mthread =new SerialThread(ui->PortBox->currentText(), ui->BaudBox->currentText().toInt(),ui->StopBox->currentText(),
                                  ui->BitBox->currentIndex(), ui->CheckBox->currentText());
        //接收子线程传输数据的信号
        connect(mthread,SIGNAL(senddata(QByteArray,int,int,int,int,int)),this,SLOT(on_showData(QByteArray,int,int,int,int,int)),Qt::QueuedConnection);
        connect(mthread,SIGNAL(senderrordata(char)),this,SLOT(on_showErrorData(char)),Qt::QueuedConnection);
        connect(mthread,SIGNAL(sendmsgbox()),this,SLOT(on_showMsgBox()),Qt::QueuedConnection);
        mthread->run();//开启子线程

        timer->stop();
        //关闭设置菜单使能
        ui->PortBox->setEnabled(false);
        ui->BaudBox->setEnabled(false);
        ui->BitBox->setEnabled(false);
        ui->CheckBox->setEnabled(false);
        ui->StopBox->setEnabled(false);
        //改变 OpenSerialButton 显示
        showFlag = 1;
        ui->OpenSerialButton->setText("关闭串口");
    }
    else
    {
        //关闭串口
        mthread->close_mthread_serial();

        timer->start(100);
        //恢复设置使能
        ui->PortBox->setEnabled(true);
        ui->BaudBox->setEnabled(true);
        ui->BitBox->setEnabled(true);
        ui->CheckBox->setEnabled(true);
        ui->StopBox->setEnabled(true);
        showFlag = 0;
        //改变 OpenSerialButton 显示
        ui->OpenSerialButton->setText("打开串口");
    }
}

//接收区清除
void MainWindow::on_cleanButton_clicked()
{
    //清空以前的显示
    ui->textEdit->clear();
}

//ascii 转 hex
void MainWindow::on_hexBox_stateChanged(int arg1)
{
    if (arg1 == Qt::Checked)
    {
        qDebug() << "1" << endl;
    }
    else if(arg1 == Qt::PartiallyChecked)
    {
        qDebug() << "2" << endl;
    }
    else
    {
        qDebug() << "0" << endl;
    }
}

//更新端口号
void MainWindow::UpdatePort()
{
    QStringList newPortStringList;
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos)
    {
        newPortStringList += info.portName();
    }
    //更新串口号
    if(newPortStringList.size() != oldPortStringList.size())
    {
        oldPortStringList = newPortStringList;
        ui->PortBox->clear();
        ui->PortBox->addItems(oldPortStringList);
    }
}

//绘图大小进行变化,启动时 和 拖动主窗口时 会调用这个事件
void MainWindow::resizeEvent(QResizeEvent *event)
{
    QMainWindow::resizeEvent(event);

    point = QPoint(ui->label_picture->width()/2,ui->label_picture->height()/2);
    //以较短的边长作为绘制区域边长
    if(ui->label_picture->width() > ui->label_picture->height())
        i_diameter = ui->label_picture->height();
    else
        i_diameter = ui->label_picture->width();

//    point = QPoint(ui->label_picture->width()/2,ui->label_picture->height()/2);
//    i_diameter = ui->label_picture->width();

    //初始化距离点为外圈距离
    for(int i=0; i < 360; i++)
    {
        points[i] = QPoint(static_cast<int>(point.x())//+sin(i/57.32f)*i_diameter/2)
                         , static_cast<int>(point.y()));//-cos(i/57.32f)*i_diameter/2));
    }
}

//QPixmap定义画布, OPen定义画笔, QConicalGradient对图形进行渐变填充, drawEllipse进行画圆
QPixmap MainWindow::paintWidget()
{
    QPixmap pixmap(ui->label_picture->width(),ui->label_picture->height());
    QPainter p_painter(&pixmap);
    QPen pen;
    QTime timedebug;
    timedebug.start();

    //pixmap.load("D:/whitt/qtProject/qt/1.png");
    //反锯齿 渲染
    p_painter.setRenderHint(QPainter::Antialiasing);
    pixmap.fill(Qt::black);
    //ui->label_picture->setPixmap(pixmap);

    //先定颜色，再画十字
    pen.setStyle(Qt::DashLine); //虚线
 //   pen.setWidth(1);
    pen.setColor(Qt::green);
    p_painter.setPen(pen);
    // drawLine画十字线 (0 0 100 100)为起点(0,0) 终点(100,100)
    for(int i=0; i<LINECOUNT; i++)//每30°画一根线
    {
        p_painter.drawLine(static_cast<int>(point.x() + sin(3.14*i/LINECOUNT)*i_diameter/2),
                           static_cast<int>(point.y() - cos(3.14*i/LINECOUNT)*i_diameter/2),
                           static_cast<int>(point.x() - sin(3.14*i/LINECOUNT)*i_diameter/2),
                           static_cast<int>(point.y() + cos(3.14*i/LINECOUNT)*i_diameter/2));

        QString distance = QString::number(180/LINECOUNT*i ,5 , 0);//起点度数
        p_painter.drawText(QPoint(static_cast<int>(point.x() + sin(3.14*i/LINECOUNT)*i_diameter/2),
                                  static_cast<int>(point.y() - cos(3.14*i/LINECOUNT)*i_diameter/2)), QString("%1°").arg(distance)); //距离刻度
        distance = QString::number(180+180/LINECOUNT*i ,5 , 0);//终点度数 放在圈外
        p_painter.drawText(QPoint(static_cast<int>(point.x() - sin(3.14*i/LINECOUNT)*i_diameter/2-20),
                                  static_cast<int>(point.y() + cos(3.14*i/LINECOUNT)*i_diameter/2)), QString("%1°").arg(distance)); //距离刻度
    }

    //先定颜色，再画圆圈
    pen.setColor(Qt::green);
    p_painter.setPen(pen);
    for(int i=0; i<=CIRCLECOUNT; i++)
    {
        if(i == CIRCLECOUNT)
        {
            p_painter.drawEllipse(QPoint(point.x(),point.y()),i_diameter*i/(2*CIRCLECOUNT) ,i_diameter*i/(2*CIRCLECOUNT)); //画个圆心和半径
            p_painter.drawText(QPoint(point.x(), point.y() - i_diameter*i/(2*CIRCLECOUNT) + 10), QString("%1cm").arg(SHOWDISTANCE)); //距离刻度
        }
        else
        {
            p_painter.drawEllipse(QPoint(point.x(),point.y()),i_diameter*i/(2*CIRCLECOUNT) ,i_diameter*i/(2*CIRCLECOUNT)); //画个圆心和半径
            QString distance = QString::number(i*((SHOWDISTANCE)/CIRCLECOUNT), 5, 0);
            p_painter.drawText(QPoint(point.x(), point.y() - i_diameter*i/(2*CIRCLECOUNT) + 10), QString("%1cm").arg(distance)); //距离刻度
        }
    }

    //打开串口再出现余晖显示
    if(1 == showFlag)
    {
        //设置点 point 为圆锥尖的点， 后面的为角度(0-360)，乘720相当于两圈，变相加快了速度
        QConicalGradient conical_gradient(point,(6.28-d_angle)/6.28*720);//定义圆心和渐变的角度
        // 参数余晖的面积是圆面积的0.1, QColor(255,255,255,0) 是RGB三个参数加透明度 0-255
        conical_gradient.setColorAt(0,Qt::green);
        conical_gradient.setColorAt(0.05,QColor(255,255,255,0));
        p_painter.setBrush(QBrush(conical_gradient));
        //p_painter.setBrush(conical_gradient);
        p_painter.drawEllipse(QPoint(point.x(),point.y()),i_diameter/2,i_diameter/2);
    }

    //装饰-随机点
    for(int i = 0; i < COUNTSIZE; ++i)
    {
        //笔颜色，宽(单位像素)，设置画笔
        p_painter.setPen(QPen(QColor(255,255,255,255), 2));
        //画点(初始化里面数组的几个点都是空的)
        p_painter.drawPoint(points[i]);
//        p_painter.drawPoint(m_points.at(i));
    }
    //连线
//    p_painter.drawPolyline(points, 360);
    //qDebug()<<"time_end="<<timedebug.elapsed()<<"ms";

    return pixmap;
}

//对paintEven进行重构 会在update()函数调用时启动
void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter p_painter(this);
    //反锯齿
    p_painter.setRenderHint(QPainter::Antialiasing);
    p_painter.drawPixmap(0,0,ui->label_picture->width(),ui->label_picture->height(),paintWidget());
    QWidget::paintEvent(event);
}

//当定时溢出时对图像进行刷新，同时重新开启定时，定时单位是毫秒
void MainWindow::timerTimeOut()
{
    p_timer->start(10);
    d_angle += 3.14/90;
    if(d_angle >= 6.28)
    {
        d_angle = 0;
    }

    //update时会调用paintEvent事件，还有repaint()函数也会调用
    update();
}

void MainWindow::on_showData(QByteArray value,int index,int data0,int data1,int data2,int data3)
{
//    qDebug()<<"index="<<index<<"data0="<<data0<<"data1="<<data1<<"data2="<<data2<<"data3="<<data3;

    ui->textEdit->append(value);

    points[index*4] = QPoint(static_cast<int>(point.x()+sin((index*4)/57.32f)*data0*i_diameter/(SHOWDISTANCE*2))
                                    , static_cast<int>(point.y()-cos((index*4)/57.32f)*data0*i_diameter/(SHOWDISTANCE*2)));
    points[index*4+1] = QPoint(static_cast<int>(point.x()+sin((index*4+1)/57.32f)*data1*i_diameter/(SHOWDISTANCE*2))
                                       , static_cast<int>(point.y()-cos((index*4+1)/57.32f)*data1*i_diameter/(SHOWDISTANCE*2)));
    points[index*4+2] = QPoint(static_cast<int>(point.x()+sin((index*4+2)/57.32f)*data2*i_diameter/(SHOWDISTANCE*2))
                                       , static_cast<int>(point.y()-cos((index*4+2)/57.32f)*data2*i_diameter/(SHOWDISTANCE*2)));
    points[index*4+3] = QPoint(static_cast<int>(point.x()+sin((index*4+3)/57.32f)*data3*i_diameter/(SHOWDISTANCE*2))
                                       , static_cast<int>(point.y()-cos((index*4+3)/57.32f)*data3*i_diameter/(SHOWDISTANCE*2)));
}

void MainWindow::on_showErrorData(char value)
{
    showbuf.append(value);

 //   ui->textEdit->insertPlainText(v);
    if(showbuf.count() > 10)
    {
        ui->textEdit->append(showbuf);
        showbuf.clear();
    }
}

void MainWindow::on_showMsgBox(void)
{
    QMessageBox::warning(this , "error!" , "open port failed!", 0, 0, QMessageBox::Ok | QMessageBox::Default);
    on_OpenSerialButton_clicked();
}

void MainWindow::on_SetButton_clicked()
{
    ushort line = ui->lineNumEdit->text().toUShort();
    ushort circle = ui->circleNumEdit->text().toUShort();
    ushort distance = ui->distanceEdit->text().toUShort();

    qDebug() << line << circle << distance;

    if(((line < 2) || (line > 12)) && (line != 0))
    {
        QMessageBox::warning(this , "error!" , "Please set the line num between 2 and 12!", 0, 0, QMessageBox::Ok | QMessageBox::Default);
        return ;
    }

    if(((circle < 2) || (circle > 12)) && (circle != 0))
    {
        QMessageBox::warning(this , "error!" , "Please set the circle num between 2 and 12!", 0, 0, QMessageBox::Ok | QMessageBox::Default);
        return ;
    }

    if(((distance < 50) || (distance > 900)) && (distance != 0))
    {
        QMessageBox::warning(this , "error!" , "Please set the distance num between 50 and 900!", 0, 0, QMessageBox::Ok | QMessageBox::Default);
        return ;
    }

    if(line != 0)//线束
        LINECOUNT = line;
    if(circle != 0)//圈束
        CIRCLECOUNT = circle;
    if(distance != 0)//显示距离
        SHOWDISTANCE = distance;
}
